package com.dynabook.ebs.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONNull;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dynabook.ebs.mapper.PcmStockTransferDesignIfMapper;
import com.dynabook.ebs.mapstruct.pcm.PcmMapper;
import com.dynabook.ebs.model.entity.DbhItemMstV;
import com.dynabook.ebs.model.entity.PcmSnDesignIf;
import com.dynabook.ebs.model.entity.PcmStockTransferDesignIf;
import com.dynabook.ebs.model.vo.EmsCategoryVO;
import com.dynabook.ebs.model.vo.ItemCodeVO;
import com.dynabook.ebs.model.vo.PcmStockTransferDesignIfVO;
import com.dynabook.ebs.service.DbhItemMstVService;
import com.dynabook.ebs.service.PcmSnDesignIfService;
import com.dynabook.ebs.service.PcmStockTransferDesignIfService;
import com.dynabook.ebs.utils.HttpGekUtil;
import com.dynabook.ebs.utils.LogUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* @author tester
* @description 针对表【PCM_STOCK_TRANSFER_DESIGN_IF】的数据库操作Service实现
* @createDate 2025-05-28 10:40:31
*/
@Service
@Slf4j
public class PcmStockTransferDesignIfServiceImpl extends ServiceImpl<PcmStockTransferDesignIfMapper, PcmStockTransferDesignIf>
    implements PcmStockTransferDesignIfService {

    @Resource
    private DbhItemMstVService dbhItemMstVService;



    @Resource
    private PcmSnDesignIfService pcmSnDesignIfService;

    @Value("${spring.ems_url}")
    private String emsUrl;




    @Override
    public List<PcmStockTransferDesignIfVO> getEBSData(String processFlag) {
        LogUtils.info(log, "Start getting EBS data with processFlag: {}", processFlag);
        try {
            // 查询主表数据
            QueryWrapper<PcmStockTransferDesignIf> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("PROCESS_FLAG", processFlag);
            List<PcmStockTransferDesignIf> pcmStockTransferDesignIfLists = this.baseMapper.selectList(queryWrapper);
            LogUtils.info(log, "Retrieved {} records from PCM_STOCK_TRANSFER_DESIGN_IF with processFlag: {}", 
                    pcmStockTransferDesignIfLists.size(), processFlag);
            
            if (CollectionUtils.isEmpty(pcmStockTransferDesignIfLists)) {
                LogUtils.info(log, "No records found with processFlag: {}, returning empty list", processFlag);
                return Collections.emptyList();
            }
            
            // 收集ebs数据
            List<String> itemCodes = pcmStockTransferDesignIfLists.stream()
                .map(PcmStockTransferDesignIf::getItemCode)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
            LogUtils.info(log, "Collected {} distinct item codes for lookup", itemCodes.size());
                
            // 批量查询样建数据
            Map<String, DbhItemMstV> itemMap = Collections.emptyMap();
            if (!CollectionUtils.isEmpty(itemCodes)) {
                QueryWrapper<DbhItemMstV> itemQueryWrapper = new QueryWrapper<>();
                itemQueryWrapper.in("PN", itemCodes);
                List<DbhItemMstV> itemList = dbhItemMstVService.list(itemQueryWrapper);
                LogUtils.info(log, "Retrieved {} records from DBH_ITEM_MST_V", itemList.size());
                
                itemMap = itemList.stream()
                    .collect(Collectors.toMap(DbhItemMstV::getPn, item -> item, (k1, k2) -> k1));
                LogUtils.info(log, "Created item map with {} entries", itemMap.size());
            }
            
            // 批量查询PcmSnDesignIf数据（解决N+1查询问题）
            // 收集所有需要查询的documentNo和itemCode组合
            List<Long> documentNos = pcmStockTransferDesignIfLists.stream()
                .map(PcmStockTransferDesignIf::getDocumentNo)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
                
            Map<String, List<PcmSnDesignIf>> pcmSnMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(documentNos)) {
                QueryWrapper<PcmSnDesignIf> pcmSnQueryWrapper = new QueryWrapper<>();
                pcmSnQueryWrapper.in("DOCUMENT_NO", documentNos);
                List<PcmSnDesignIf> pcmSnList = pcmSnDesignIfService.list(pcmSnQueryWrapper);
                LogUtils.info(log, "Retrieved {} records from PCM_SN_DESIGN_IF", pcmSnList.size());
                
                // 建立映射：documentNo_itemCode -> List<PcmSnDesignIf>
                pcmSnMap = pcmSnList.stream()
                    .filter(sn -> sn.getDocumentNo() != null && sn.getItemCode() != null)
                    .collect(Collectors.groupingBy(sn -> sn.getDocumentNo() + "_" + sn.getItemCode()));
                LogUtils.info(log, "Created PcmSn map with {} entries", pcmSnMap.size());
            }
            
            // 组装返回数据
            final Map<String, DbhItemMstV> finalItemMap = itemMap;
            final Map<String, List<PcmSnDesignIf>> finalPcmSnMap = pcmSnMap;
            List<ItemCodeVO> missingItemCodes = Collections.synchronizedList(new ArrayList<>());
            List<PcmStockTransferDesignIfVO> pcmStockTransferDesignIfVOS = pcmStockTransferDesignIfLists.stream()
                .flatMap(item -> {
                    String oaRequestId = item.getOaRequestId();
                    String itemCode = item.getItemCode();
                    DbhItemMstV dbhItemMstV = itemCode != null ? finalItemMap.get(itemCode) : null;
                    PcmStockTransferDesignIfVO baseVO = PcmMapper.INSTANCE.PcmToPcmVO(item, dbhItemMstV);
                    
                    // 判断分类表中是否存在对应的item_code
                    JSONObject body = new JSONObject();
                    
                    // 处理itemCode：如果长度为16，从缓存的PcmSnDesignIf数据中获取Pno
                    if(itemCode != null && itemCode.length() == 16){
                        String mapKey = item.getDocumentNo() + "_" + itemCode;
                        List<PcmSnDesignIf> pnoList = finalPcmSnMap.get(mapKey);
                        
                        if (!CollectionUtils.isEmpty(pnoList)) {
                            // 取第一条记录的Pno作为itemCode参数
                            String pno = pnoList.get(0).getPno();
                            if (pno != null) {
                                body.set("itemCode", pno);
                                LogUtils.info(log, "itemCode长度为16，使用查询到的Pno: {} 替代原itemCode: {}", pno, itemCode);
                            } else {
                                LogUtils.warn(log, "itemCode: {} 查询到Pno为null，使用原itemCode", itemCode);
                                body.set("itemCode", itemCode);
                            }
                        } else {
                            LogUtils.warn(log, "itemCode: {} 未查询到对应的PcmSnDesignIf记录，使用原itemCode", itemCode);
                            body.set("itemCode", itemCode);
                        }
                    } else {
                        body.set("itemCode", itemCode);
                    }

                    
                    // 使用try-with-resources确保资源关闭
                    try (HttpResponse checkItemCode = HttpGekUtil.post(emsUrl + "getCategoryByItemCode", body)) {
                        LogUtils.info(log, "checkItemCode: {}", checkItemCode);
                        // 解析 JSON 响应
                        JSONObject jsonObject = new JSONObject(checkItemCode.body());
                        // 判断 data 是否存在且不为 null
                        if (jsonObject.containsKey("data") && !jsonObject.get("data").equals(JSONNull.NULL)) {
                            // 正确地将 data 转换为 EmsCategoryVO 对象
                            EmsCategoryVO data = jsonObject.getJSONObject("data").toBean(EmsCategoryVO.class);
                            String bigCategory = data.getBigCategory();
                            String category = data.getCategory();
                            Long quantity = baseVO.getQuantity();
                            
                            switch (bigCategory) {
                                case "Machine":
                                    // 从缓存的数据中获取PcmSnDesignIf列表，避免重复查询
                                    String machineMapKey = item.getDocumentNo() + "_" + item.getItemCode();
                                    List<PcmSnDesignIf> dbhSnList = finalPcmSnMap.getOrDefault(machineMapKey, Collections.emptyList());
                                    
                                    // 如果dbhSnList为空，返回包含baseVO的Stream以避免返回null
                                    if (CollectionUtils.isEmpty(dbhSnList)) {
                                        baseVO.setCategory(category);
                                        baseVO.setBigCategory(bigCategory);
                                        return Stream.of(baseVO);
                                    }
                                    
                                    return dbhSnList.stream().map(dbhSn -> {
                                        PcmStockTransferDesignIfVO vo = new PcmStockTransferDesignIfVO();
                                        BeanUtils.copyProperties(baseVO, vo);
                                        vo.setSn(dbhSn.getSerialNo());
                                        vo.setCategory(category);
                                        vo.setBigCategory(bigCategory);
                                        vo.setPno(dbhSn.getPno());
                                        return vo;
                                    });
                                case "PCBA":
                                case "Unit":
                                    baseVO.setCategory(category);
                                    baseVO.setBigCategory(bigCategory);
                                    if (quantity == null || quantity <= 1) {
                                        return Stream.of(baseVO);
                                    } else {
                                        // 根据quantity数量复制baseVO并返回多个副本
                                        return Stream.iterate(0, i -> i + 1)
                                                .limit(quantity)
                                                .map(i -> {
                                                    PcmStockTransferDesignIfVO vo = new PcmStockTransferDesignIfVO();
                                                    BeanUtils.copyProperties(baseVO, vo);
                                                    vo.setCategory(category);
                                                    vo.setBigCategory(bigCategory);
                                                    return vo;
                                                });
                                    }
                                case "Part":
                                    baseVO.setCategory(category);
                                    baseVO.setBigCategory(bigCategory);
                                    return Stream.of(baseVO);
                                default:
                                    // 对于未知类别，设置默认类别并返回baseVO
                                    LogUtils.warn(log, "未知category: {} for item code: {}", bigCategory, itemCode);
                                    return null;
                            }
                        } else {
                            LogUtils.warn(log, "分类表不存在对应的item_code: {}", itemCode);
                            ItemCodeVO itemCodeVO = new ItemCodeVO();
                            itemCodeVO.setItemCode(itemCode);
                            itemCodeVO.setOaRequestId(oaRequestId);
                            missingItemCodes.add(itemCodeVO);
                            return null;
                        }
                    } catch (Exception e) {
                        LogUtils.error(log, "[EBS]查询异常", e, itemCode);
                        return null;
                    }
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
            if(!CollectionUtil.isEmpty(missingItemCodes)){
                handleMissingItemCodes(missingItemCodes);
            }
            LogUtils.info(log, "Assembled {} VO objects for response", pcmStockTransferDesignIfVOS.size());
                
            LogUtils.info(log, "完成请求ebs: {}", processFlag);
            return pcmStockTransferDesignIfVOS;
        } catch (Exception e) {
            // 记录错误日志
            LogUtils.error(log, "Failed to get EBS data with processFlag: {}", e, processFlag);
            return Collections.emptyList();
        }
    }
    private void handleMissingItemCodes(List<ItemCodeVO> missingItemCodes) {
        try {
            // 在这里实现第三方请求逻辑
            JSONObject requestBody = new JSONObject();
            requestBody.set("missingItemCodes", missingItemCodes);
            // 示例：发起第三方请求
            HttpResponse response = HttpGekUtil.post(emsUrl + "/handleMissingItems", requestBody);
            LogUtils.info(log, "请求EBS处理邮件: {}", response);
            // 根据需要处理响应结果
        } catch (Exception e) {
            LogUtils.error(log, "请求EBS处理邮件失败" , e);
        }
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateFlag(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        List<PcmStockTransferDesignIf> updateList = ids.stream().map(id -> {
            PcmStockTransferDesignIf entity = new PcmStockTransferDesignIf();
            entity.setSequenceId(id);
            entity.setProcessFlag("1");
            return entity;
        }).collect(Collectors.toList());
        return this.updateBatchById(updateList);
    }
}




